package com.smartmail.receiving.pop3;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

import android.content.Context;
import android.content.Intent;
import android.util.Log;

import com.smartmail.SmartMailPreferences;
import com.smartmail.accounts.MailAccount;
import com.smartmail.mailing.MailMessage;
import com.smartmail.receiving.AbstractMessageHandler;
import com.smartmail.receiving.InternalStorageUtility;
import com.smartmail.receiving.IncomingMailDBManager;
import com.smartmail.receiving.Receiving;
import com.smartmail.utility.MessageUtility;

/**
 * Implementation of AbstractMessageHandler class.
 * This class is  responsible for handling new messages from POP3 mailbox.
 * 
 * @author Tomek
 *
 */
public class POP3MessageHandler extends AbstractMessageHandler {

	
	/**
	 * Public construtor.
	 * 
	 * @param context - application context
	 * @param mailAccount - Messages from this mailbox account will be handled
	 */
	public POP3MessageHandler(Context context, MailAccount mailAccount){
		
		super(context,mailAccount);
	}
	/**
	 * do appopriate actions with mime message object from email store
	 * 
	 * @param mimeMessage
	 *            - mime message object
	 * @param account
	 *            - mail Account
	 */
	
	/**
	 * This method handles one MimeMessage object (mail message) from the Inbox.
	 * First, it is checked whether this message is already stored in device.
	 * If this is known message nothing is to do.
	 * Secondly, message headers are saved in incomimg mails database.
	 * If message is small enough whole message is downloaded and 
	 * stored in device's memory. If message is new NEW_MESSAGE_DOWNLOADED_INTENT is sent.
	 * 
	 * @param mimeMessage - message object which will be handled
	 * @param messageUID -  UID field of message
	 * @return - one of the four fields :
	 * - HANDLE_ERROR 					- for failure purposes
	 * - HANDLE_NEW_MESSAGE 				- when mimeMessage is new, and info about is saved in device
	 * - HANDLE_NEW_MESSAGE_DOWNLOADED	- when mimeMessage is new, and is completely downloaded to device
	 * - HANDLE_KNOWN_MESSAGE 			- when mimeMessage is already stored in device
	 */
	@Override
	public int handle(MimeMessage mimeMessage, String messageUID) {
		try {
			
			IncomingMailDBManager dbManager = Receiving.getDBManager(_mailAccount.getAccountID());
			
			/**
			 * check if this message is already in device
			 * 
			 * this is completely new message
			 * save its headers in database and check if
			 * it could be downloaded
			 */
			if (!dbManager.isAlreadyInDB(mimeMessage)) {

				/**
				 * if writing to database succeed send intent
				 */
				if(dbManager.writeMessageHeaders(mimeMessage,messageUID,_mailAccount)){
				
					// send intent to refresh AccountMsgActivity
					Intent intent = new Intent(Receiving.NEW_MESSAGE_ARRIVED_INTENT);
					intent.putExtra(Receiving.MAIL_INFO_ACCOUNT_ID, _mailAccount.getAccountID());
					intent.putExtra(Receiving.MAIL_INFO_HASH, MessageUtility.getHash(mimeMessage));
					_context.sendBroadcast(intent);
					
					Log.d(_logTag, "POP3MessageHandler : New Message : " + mimeMessage.getSubject() + " - " 
							+ _mailAccount.getMailAddress());
				}	
				else
					return HANDLE_ERROR;
				
				/**
				 * now check if this message could be automically downloaded
				 */
				// maximal size of message to be automically downloaded
				long maxAutoDownload = SmartMailPreferences.getLong(SmartMailPreferences.PREFERENCE_MAX_SIZE_OF_AUTO_DOWNLOADED_MESSAGE);
				long messageSize = (long)mimeMessage.getSize();
				
				// download message
				if( messageSize > 0 && messageSize < maxAutoDownload)
					return download(mimeMessage);
				// only wrote message headers, without downloading whole message
				else
					return HANDLE_NEW_MESSAGE;
			}
			else
				return HANDLE_KNOWN_MESSAGE;

		} catch (MessagingException e) {
			
			Log.d(_logTag, "POP3MessageHandler : error while serving mimemessage" + " - " 
					+ _mailAccount.getMailAddress());
			return HANDLE_ERROR;
		}
		
	}

	/**
	 * The method used to download the complete message from the server.
	 * This method is only used for the POP3 protocol.
	 * Message is completely downloaded to device's memory. Database is refreshed.
	 * If downloading succeed MESSAGE_DOWNLOADED_INTENT is sent.
	 * 
	 * @param mimeMessage - message object wanted to be downloaded
	 * @return - one of the three fields :
	 * - HANDLE_ERROR 					- for failure purposes
	 * - HANDLE_NEW_MESSAGE_DOWNLOADED	- when mimeMessage is new, and is completely downloaded to device
	 * - HANDLE_KNOWN_MESSAGE 			- when mimeMessage is already stored in device
	 */
	public int download(MimeMessage mimeMessage) {

		try {
			
			String messageHash = MessageUtility.getHash(mimeMessage);
			IncomingMailDBManager dbManager = Receiving.getDBManager(_mailAccount.getAccountID());

			String path = InternalStorageUtility.POP3.writeWholeMessageOnSDCard(mimeMessage);
			boolean pathResult = dbManager.setPath(path, mimeMessage);
			boolean stateResult = dbManager.setState(MailMessage._MESSAGE_DOWNLOADED_NOT_READ,
					mimeMessage);
			
			/**
			 * if all previous actions succeed
			 */
			if( path!= null && pathResult && stateResult){
				
				// send appropriate intent to AccountMsgActivity (by
				// MessageInfoReceiver)
				Intent msgInfoIntent = new Intent(Receiving.MESSAGE_DOWNLOADED_INTENT);
				msgInfoIntent.putExtra(Receiving.MAIL_INFO_HASH, messageHash);
				msgInfoIntent.putExtra(Receiving.MAIL_INFO_ACCOUNT_ID, _mailAccount.getAccountID());
				_context.sendBroadcast(msgInfoIntent);
			
			} else{
				
				Log.d(_logTag, "POP3MessageHandler : error while download" + " - " 
						+ _mailAccount.getMailAddress());
				return HANDLE_ERROR;
			}
				

		} catch (MessagingException e) {

			Log.d(_logTag, "POP3MessageHandler : error while serving mimemessage" + " - " 
					+ _mailAccount.getMailAddress());
			return HANDLE_ERROR;
		}
		
		return HANDLE_NEW_MESSAGE_DOWNLOADED;
	}

}
